package logica;

import uniandes.cupi2.collections.arbol.arbolBinario.*;

public class NodoGrafo implements Comparable<NodoGrafo> {

	//-------------------------------------------------------
	// Atributos
	//-------------------------------------------------------
	
	private ArbolBinario<String> arbolEstado;
	
	private int heuristica;

	private int id;

	private int idPadre;
	
	private String variable;

	private boolean variableAislada;
	
	//-------------------------------------------------------------------------------------------------
	// Metodos constructores
	//-------------------------------------------------------------------------------------------------
	
	public NodoGrafo(int nId, ArbolBinario<String> nuevo, int padre, String variable){
		idPadre = padre;
		arbolEstado = nuevo;
		id = nId;
		variableAislada = evaluarVariable();
		heuristica = calcularHeuristica();
	}
	
	private boolean evaluarVariable(){
		boolean hayVariable = false;
		NodoArbolBinario<String> raiz = arbolEstado.darRaiz();
		if (raiz.darIzquierdo() != null) {
			hayVariable = hayVariable(variable, raiz.darIzquierdo());
		}
		if (raiz.darDerecho() != null) {
			hayVariable = !(hayVariable && hayVariable(variable, arbolEstado
					.darRaiz().darDerecho()));
		}
		return hayVariable;
	}
	
	private boolean hayVariable(String variable, NodoArbolBinario<String> nodo) {

		if (nodo.darElemento().equals(variable)) {
			return true;
		} else {
			if (nodo.darIzquierdo() != null) {
				if(hayVariable(variable, nodo.darIzquierdo()))
					return true;
			}
			if (nodo.darDerecho() != null) {
				if(hayVariable(variable, nodo.darDerecho()))
					return true;
			}
			return false;
		}
	}
	
	private int calcularHeuristica(){
		int heuristica = 0;

		if (variableAislada) {
			heuristica += 15;
		}

		heuristica += arbolEstado.contarHojas();
		heuristica += arbolEstado.darPeso();
		heuristica += contarVariables(0, arbolEstado.darRaiz());

		return heuristica;

	}
	
	//--------------------------------------------------------------------------------------------------
	// Getters
	//--------------------------------------------------------------------------------------------------
	
	public int darHeuristica(){
		return heuristica;
	}
	
	public int darId(){
		return id;
	}
	
	public int darIdPadre(){
		return idPadre;
	}
	
	public boolean esAislada(){
		return variableAislada;
	}
	
	public ArbolBinario<String> darArbol(){
		return arbolEstado;
	}
	
	//-------------------------------------------------------------------------------------------------------
	// Metodo auxiliar
	//-------------------------------------------------------------------------------------------------------
	
	@Override
	public int compareTo(NodoGrafo arg0) {
		if (darHeuristica() > arg0.darHeuristica())
			return 1;
		else if (darHeuristica() == arg0.darHeuristica())
			return 0;
		else
			return -1;
	}
	
	public static int contarVariables(int cant, NodoArbolBinario<String> nodo){
		if (nodo.darElemento().equals(solucionador.variableDespejar)) {
			return cant++;
		} else if (nodo.darIzquierdo() != null) {
			return contarVariables(cant, nodo.darIzquierdo());
		} else if (nodo.darDerecho() != null) {
			return contarVariables(cant, nodo.darDerecho());
		} else
			return cant;
	}
}